package com.minelx.woods.task.core;

import com.minelx.sqlstructures.statements.clause.Field;
import com.minelx.statementsplus.ChildSqlBuilder;
import com.minelx.statementsplus.IChildSqlBuilder;
import com.minelx.woods.task.core.values.FieldPathValues;

import java.util.*;

public class FieldCollector {
	private final List<FieldPathValues> tableAndFields;

	private final FieldFactory fieldFactory;

	public FieldCollector() {
		tableAndFields = new LinkedList<>();
		fieldFactory = new FieldFactory();
	}

	public void add(FieldPathValues added) {
		tableAndFields.add(added);
	}

	public List<IChildSqlBuilder> toChildSqlBuilders() {
		Map<String, IChildSqlBuilder> result = new HashMap<>();
		for (FieldPathValues tableAndField : tableAndFields) {
			Field field = fieldFactory.createField(tableAndField);
			putIfAbsent(result, tableAndField.getTableName())
					.addField(field);
		}

		// FIXME 2021/7/14  wait for me!!!     We'll find another way
		LinkedList<IChildSqlBuilder> returns = new LinkedList<>(result.values());
		Optional<IChildSqlBuilder> proxyChildSql = returns.stream().filter(which -> which.asSql().toText().contains("proxy_id")).findFirst();
		if (proxyChildSql.isPresent()) {
			IChildSqlBuilder target = proxyChildSql.get();
			// move it to the end
			returns.remove(target);
			returns.add(target);
		}
		return returns;
	}

	private IChildSqlBuilder putIfAbsent(Map<String, IChildSqlBuilder> context, String tableName) {
		if (context.containsKey(tableName)) { // there is a table already
			return context.get(tableName);
		}
		// there is no table for this name
		IChildSqlBuilder result = ChildSqlBuilder.create(parentKeyOf(tableName), tableName);
		context.put(tableName, result);
		return result;
	}

	// FIXME 2021/8/30  THIS METHOD NEEDED TEST SUPPORT!
	public static List<IChildSqlBuilder> collect(List<FieldPathValues> tableAndFields) {
		FieldCollector result = new FieldCollector();
		tableAndFields.forEach(result::add);
		return result.toChildSqlBuilders();
	}

	// FIXME 2021/8/27  wait for me!!!      actually primaryKeyOf
	private static String parentKeyOf(String tableName) {
		if (tableName.equals("t_d_proxy")) {
			return "proxy_id";
		} else if (tableName.equals("t_d_salesman")) {
			return "salesman_id";
		} else {
			return "member_id";
		}
	}
}
